perm filename WEAVE.CH[WEB,ALS] blob
sn#652106 filedate 1982-04-10 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00013 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 @ Some of this code is optional for use when debugging only
C00005 00003 @ Here now is the system-dependent part of the character set.
C00006 00004 @ The following code opens the input files. Since these files were listed
C00008 00005 @ The following code opens |tex_file|. Since this file was listed in the
C00009 00006 @ Input goes into an array called |buffer|.
C00010 00007 @p function input_ln(var f:text_file):boolean
C00012 00008 @<Print error location based on input buffer@>=
C00014 00009 @ When we wish to append the character $c$ to the output buffer, we write
C00016 00010 @<Print error message and prepare to write...@>=
C00018 00011 @ @<If tracing,...@>=
C00019 00012 @<Output the code...@>=
C00020 00013 @<Phase III: Output the cross-reference index@>=
C00021 ENDMK
C⊗;
@ Some of this code is optional for use when debugging only;
such material is enclosed between the delimiters |debug| and $|gubed|$.
Other parts, delimited by |stat| and $|tats|$, are optionally included
if statistics about \.{WEAVE}'s memory usage are desired.
@d debug==@{ {change this to `$\\{debug}\eqv\null$' when debugging}
@d gubed==@} {change this to `$\\{gubed}\eqv\null$' when debugging}
@f debug==begin
@f gubed==end
@#
@d stat== {change this to `$\\{stat}\eqv\.{@@\}}$' when not
gathering usage statistics}
@d tats== {change this to `$\\{tats}\eqv\.{@@\}}$' when not
gathering usage statistics}
@f stat==begin
@f tats==end
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ Here now is the system-dependent part of the character set.
The code shown here is intended to be used on the Stanford {\sc SAIL} system,
and at other installations like CMU and ISI where essentially the same
extended character set is used. The fact that {\sc SAIL} has |'}'| in the
wrong place turns out to cause no difficulty in this case.
@<Set initial values...@>=
for i←1 to @'37 do xchr[i]←chr(i);
xchr[left_arrow]←chr(@'137);
xchr[not_equal]←chr(@'33);
xchr[@'33]←chr(@'176);
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ The following code opens the input files. Since these files were listed
in the program header, we assume that the \PASCAL\ runtime system has
already checked that suitable file names have been given; therefore
no additional error checking needs to be done. We open the files
in a special mode that allows us to distinguish |form_feed| from
|carriage_return|. We will see below that \.{WEAVE} reads through the
entire input twice.
Local scuttlebutt says that nineteen buffers gives best results at {\mc SAIL}.
@p procedure open_input; {prepare to read |web_file| and |change_file|}
begin reset(web_file,'','/E/N:19'); reset(change_file,'','/E/N:19');
end;
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ The following code opens |tex_file|. Since this file was listed in the
program header, we assume that the \PASCAL\ runtime system has checked
that a suitable external file name has been given.
@↑system dependencies@>
@<Set init...@>=
rewrite(tex_file,'','/N:19');
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ Input goes into an array called |buffer|.
We use a special feature of the local \PASCAL\ that
reads text into another array |aux_buffer| first, thus saving
a bunch of procedure-call overhead.
@<Globals...@>=@!buffer: array[0..long_buf_size] of ascii_code;
@!aux_buffer:array[0..buf_size] of text_char;
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@p function input_ln(var f:text_file):boolean;
{inputs a line or returns |false|}
label restart;
var n: integer; {the number of characters input by Hedrick's extended |read|}
@!k:0..buf_size; {index into the buffers}
begin restart: if eof(f) then
begin limit←0; input_ln←false;
end
else begin read(f,aux_buffer:n);
if (line=1)∧(n=29)∧(aux_buffer[0]='C')∧(aux_buffer[8]=chr(@'26)) then
begin while (f↑≠chr(form_feed))∧(not eof(f)) do
begin read_ln(f);
read(f,aux_buffer:n); {skip file directory page}
end;
end;
if n<buf_size then
begin limit←n;
if n>0 then for k←0 to limit-1 do buffer[k]←xord[aux_buffer[k]]
else if f↑=chr(form_feed) then
begin line←((line div @'200000)+1)*@'200000+1;
read_ln(f); goto restart;
end;
end
else begin limit←buf_size-1;
for k←0 to limit-1 do buffer[k]←xord[aux_buffer[k]];
print_nl('! Input line too long'); error;
@.Input line too long@>
while not eoln(f) do read(f,aux_buffer);
end;
read_ln(f); input_ln←true;
end;
end;
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@<Print error location based on input buffer@>=
begin if changing then print('. (change file ')@+else print('. (');
print_ln('p.',1+(line div @'200000):0,',l.', line mod @'200000:0, ')');
if loc≥limit then l←limit else l←loc;
for k←1 to l do
if buffer[k-1]=tab_mark then print(' ')
else print(xchr[buffer[k-1]]); {print the characters already read}
new_line;
for k←1 to l do print(' '); {space out the next line}
for k←l+1 to limit do print(xchr[buffer[k-1]]); {print the part not yet read}
if buffer[limit]="|" then print(xchr["|"]);
{end of \PASCAL\ text in module names}
print(' '); {this space separates the message from future asterisks}
end
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ When we wish to append the character $c$ to the output buffer, we write
`$|out|(c)$'; this will cause the buffer to be emptied if it was already
full. Similarly, `$|out2|(c↓1)(c↓2)$' appends a pair of characters.
A line break will occur at a space or after a single-nonletter
\TEX\ control sequence. The |write_end_of_page| routine is used to
break the output into pages for ease in editing.
@d oot(#)==if out_ptr=line_length then break_out;
incr(out_ptr); out_buf[out_ptr]←#;
@d oot1(#)==oot(#)@+end
@d oot2(#)==oot(#)@,oot1
@d oot3(#)==oot(#)@,oot2
@d oot4(#)==oot(#)@,oot3
@d oot5(#)==oot(#)@,oot4
@d out==@+begin oot1
@d out2==@+begin oot2
@d out3==@+begin oot3
@d out4==@+begin oot4
@d out5==@+begin oot5
@p procedure write_end_of_page;
begin if out_ptr>0 then flush_buffer(out_ptr);
write(tex_file,xchr[form_feed]); {write a page mark}
out_line←((out_line div @'200000)+1)*@'200000+1;
end;
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@<Print error message and prepare to write...@>=
begin print_nl('! Line had to be broken (output p.',
@.Line had to be broken@>
1+(out_line div @'200000):0,',l.',out_line mod @'200000:0);
print_ln('):');
for k←1 to out_ptr do print(xchr[out_buf[k]]);
new_line; k←out_ptr; c←" ";
end
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@ @<If tracing,...@>=
debug if tracing=2 then
begin print_nl('Tracing after p.',1+(line div @'200000):0,
',l.',line mod @'200000:0,':');
if loc>50 then
begin print('...');
for k←loc-50 to loc do print(xchr[buffer[k-1]]);
end
else for k←1 to loc do print(xchr[buffer[k-1]]);
end
gubed
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@<Output the code...@>=
finish_line; flush_buffer(0); {insert a blank line, it looks nice}
if buffer[loc-1]≠"*" then out2("\")("M")
else begin write_end_of_page;
out2("\")("N");
print(module_count:0,','); update_terminal; {print a progress report}
end;
out_val(module_count); out2(".")(" ")
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z
@<Phase III: Output the cross-reference index@>=
print_nl('Writing the index...');
finish_line; write_end_of_page;
out4("\")("i")("n")("x"); finish_line;
@<Do the first pass of sorting@>;
@<Sort and output the index@>;
write_end_of_page;
out4("\")("f")("i")("n"); finish_line;
@<Output all the module names@>;
out4("\")("c")("o")("n"); finish_line;
print('Done.');
@↑system dependencies@>@↑changes for {\mc SAIL}@>@z